package com.moyun.finance.service;

import com.moyun.finance.entity.*;
import com.moyun.finance.repository.*;
import com.moyun.finance.utils.BaseUtil;
import com.moyun.finance.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

@Service
public class BillService {
    @Autowired
    BillRepository br;
    @Autowired
    AccountRepository ar;
    @Autowired
    ContractRepository cr;
    @Autowired
    ReceivablesRepository rr;
    @Autowired
    OrgUserRepository our;
    @Autowired
    ProjectsRepository pr;
    @Autowired
    CustomerRepository cusr;
    @Autowired
    ProductContractMidRepository pcmr;
    @Autowired
    ReimbursementRepository reir;

    public Response save(Bill b){
        b.setId(BaseUtil.uuid());
        Date now = new Date();
        String nowStr = DateUtils.formatDate(now);
        b.setCreateDate(nowStr);
        Account a = ar.findById(b.getAccountId()).orElse(null);//关联账户
        BigDecimal nowMoney = new BigDecimal(a.getNowMoney());
        BigDecimal billMoney = new BigDecimal(b.getBillMoney());
        BigDecimal outMoney = new BigDecimal(a.getOutMoney());
        BigDecimal inMoney = new BigDecimal(a.getInMoney());
        if(b.getBillType() == 0){//如果是支出的账单
            nowMoney = nowMoney.subtract(billMoney);//现在账户余额=原本账户余额-账单支出金额
            outMoney = outMoney.add(billMoney);
            a.setOutMoney(outMoney.doubleValue());
        }else{
            nowMoney = nowMoney.add(billMoney);
            inMoney = inMoney.add(billMoney);
            a.setInMoney(inMoney.doubleValue());
        }
        a.setNowMoney(nowMoney.doubleValue());
        ar.save(a);//更新账户现余额
        br.save(b);//保存流水账单
        return new Response("流水保存成功!",true);
    }

    public Response update(Bill newBill){
        Bill oldBill = br.findById(newBill.getId()).orElse(null);
        //流水金额 流水类型(收入支出) 流水账户 不变时直接更改
        if(oldBill.getBillType() == newBill.getBillType() && oldBill.getAccountId().equals(newBill.getAccountId()) && oldBill.getBillMoney() == newBill.getBillMoney()){
            br.save(newBill);
            return new Response("流水信息修改成功!",true);
        }
        Account oldAccount = ar.findById(oldBill.getAccountId()).orElse(null);//旧账单关联账户
        BigDecimal oldAccountNowMoney = new BigDecimal(oldAccount.getNowMoney());
        BigDecimal oldBillMoney = new BigDecimal(oldBill.getBillMoney());
        BigDecimal oldOutMoney = new BigDecimal(oldAccount.getOutMoney());
        BigDecimal oldInMoney = new BigDecimal(oldAccount.getInMoney());
        if(oldBill.getBillType() == 0){//如果就账单是支出账单
            oldAccountNowMoney = oldAccountNowMoney.add(oldBillMoney);//旧余额加上账单支出金额 还原此账单支出的金额
            oldOutMoney = oldOutMoney.subtract(oldBillMoney);
            oldAccount.setOutMoney(oldOutMoney.doubleValue());
        }else{
            oldAccountNowMoney = oldAccountNowMoney.subtract(oldBillMoney);
            oldInMoney = oldInMoney.subtract(oldBillMoney);
            oldAccount.setInMoney(oldInMoney.doubleValue());
        }
        oldAccount.setNowMoney(oldAccountNowMoney.doubleValue());
        ar.save(oldAccount);//旧账户余额还原

        Account a = ar.findById(newBill.getAccountId()).orElse(null);//关联账户
        BigDecimal nowMoney = new BigDecimal(a.getNowMoney());
        BigDecimal billMoney = new BigDecimal(newBill.getBillMoney());
        BigDecimal outMoney = new BigDecimal(a.getOutMoney());
        BigDecimal inMoney = new BigDecimal(a.getInMoney());
        if(newBill.getBillType() == 0){//如果是支出的账单
            nowMoney = nowMoney.subtract(billMoney);//现在账户余额=原本账户余额-账单支出金额
            outMoney = outMoney.add(billMoney);
            a.setOutMoney(outMoney.doubleValue());
        }else{
            nowMoney = nowMoney.add(billMoney);
            inMoney = inMoney.add(billMoney);
            a.setInMoney(inMoney.doubleValue());
        }
        a.setNowMoney(nowMoney.doubleValue());
        ar.save(a);//更新账户现余额
        br.save(newBill);//更新流水账单
        return new Response("流水信息修改成功!",true);
    }

    public Response delete(Bill b){
        //旧账户余额还原
        Account a = ar.findById(b.getAccountId()).orElse(null);//关联账户
        BigDecimal oldAccountNowMoney = new BigDecimal(a.getNowMoney());
        BigDecimal oldBillMoney = new BigDecimal(b.getBillMoney());
        BigDecimal oldOutMoney = new BigDecimal(a.getOutMoney());
        BigDecimal oldInMoney = new BigDecimal(a.getInMoney());
        if(b.getBillType() == 0){//如果就账单是支出账单
            oldAccountNowMoney = oldAccountNowMoney.add(oldBillMoney);//旧余额加上账单支出金额 还原此账单支出的金额
            oldOutMoney = oldOutMoney.subtract(oldBillMoney);
            a.setOutMoney(oldOutMoney.doubleValue());
        }else{
            oldAccountNowMoney = oldAccountNowMoney.subtract(oldBillMoney);
            oldInMoney = oldInMoney.subtract(oldBillMoney);
            a.setInMoney(oldInMoney.doubleValue());
        }
        a.setNowMoney(oldAccountNowMoney.doubleValue());
        ar.save(a);
        br.delete(b);
        return new Response("流水删除成功",true);
    }

    //本公司所有流水列表展示
    public List<Bill> findAll(String companyId){
        List<Bill> bills =  br.findByCompanyId(companyId);
        return bills;
    }

    //根据id详细信息
    public Bill findOneById(String billId){
        Bill b = br.findById(billId).orElse(null);
        if(b != null){
            OrgUser user = our.findById(b.getUserId()).orElse(null);//用户信息
            Projects p = pr.findById(b.getProjectsId()).orElse(null);//项目
            Customer cus = cusr.findById(b.getCustomerId()).orElse(null);//客户
            Contract contract = cr.findById(b.getContractId()).orElse(null);//合同
            List<ProductContractMid> productContractMids = pcmr.findByContractId(b.getContractId());//合同关联产品信息
            Account account = ar.findById(b.getAccountId()).orElse(null);
            Reimbursement reimbursement = reir.findById(b.getReimbursementId()).orElse(null);
            b.setCustomer(cus);
            b.setProjects(p);
            b.setUser(user);
            b.setContract(contract);
            b.setProductContractMids(productContractMids);
            b.setAccount(account);
            b.setReimbursement(reimbursement);
        }
        return b;
    }

    public List<Bill> findByAccount(String accountId){
        List<Bill> bills =  br.findByAccountId(accountId);
        return bills;
    }
}
